/*
 * Licensed by the Bunie Developmentgroup
 */
package gui;

import config.Content;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Arc2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import javax.swing.JLabel;
import javax.swing.JPanel;

/**
 * PieChartPanel is the class that draws a Pie Chart.
 * @author Kay van Bree
 */
public class PieChartPanel extends JPanel implements ManagementPanel {
	
	// The possible colors in the Chart, in order of usage
	private final Color[] color = new Color[]{
		Color.BLUE, Color.RED, Color.YELLOW, Color.CYAN, Color.GREEN, Color.MAGENTA, Color.ORANGE, Color.PINK,
		new Color(0, 0, 0), new Color(0, 0, 64), new Color(0, 0, 128), new Color(0, 0, 192), new Color(0, 0, 255),
		new Color(0, 64, 0), new Color(0, 64, 64), new Color(0, 64, 128), new Color(0, 64, 192), new Color(0, 64, 255),
		new Color(0, 128, 0), new Color(0, 128, 64), new Color(0, 128, 128), new Color(0, 128, 192), new Color(0, 128, 255),
		new Color(0, 192, 0), new Color(0, 192, 64), new Color(0, 192, 128), new Color(0, 192, 192), new Color(0, 192, 255),
		new Color(0, 255, 0), new Color(0, 255, 64), new Color(0, 255, 128), new Color(0, 255, 192), new Color(0, 192, 255),
		new Color(64, 0, 0), new Color(64, 0, 64), new Color(64, 0, 128), new Color(64, 0, 192), new Color(64, 0, 255),
		new Color(64, 64, 0), new Color(64, 64, 64), new Color(64, 64, 128), new Color(64, 64, 192), new Color(64, 64, 255),
		new Color(64, 128, 0), new Color(64, 128, 64), new Color(64, 128, 128), new Color(64, 128, 192), new Color(64, 128, 255),
		new Color(64, 192, 0), new Color(64, 192, 64), new Color(64, 192, 128), new Color(64, 192, 192), new Color(64, 192, 255),
		new Color(64, 255, 0), new Color(64, 255, 64), new Color(64, 255, 128), new Color(64, 255, 192), new Color(64, 192, 255)
	};
	
	private final int cap;
	private final int width;
	private final int height;
	private String infoName;
	private ArrayList<String[]> info;
	private int sum;
	private ArrayList<Slice> slices;

	/**
	 * Creates a new PieChartPanel. The dimensions and the cap are set.
	 * @author Kay van Bree
	 */
	public PieChartPanel() {
		super();
		
		// Defines the sizes of this panel
		width = 800;
		height = 480;
		setSize((int) width, (int) height);
		
		// The maximum number of results to show
		cap = 50;
		this.infoName = "Management information";
		this.add(new JLabel("No query selected yet. Please select a query from the menu to your left."));
	}
	
	/**
	 * Creates an arraylist of Slices, based on the provided info list.
	 * Please make sure to provide the right arraylist, or it won't work!
	 * @author Kay van Bree
	 * @param info An array list of String[] 0 => name, 1 => value!
	 */
	@Override
	public void setManagementInfo(ArrayList<String[]> info) {
		reset();
		this.info = info;

		// Set important values
		this.sum = getSum(info);

		this.slices = new ArrayList();
		int i = 0;
		for(String[] slice: info){
			Slice newSlice = new Slice(slice[0], Integer.valueOf(slice[1]), color[i]);
			System.out.println("Adding slice: " + newSlice.toString());
			slices.add(newSlice);
			i++;
		}
		validate();
		repaint();
	}
	
	/**
	 * Resets the panel, taken from TablePanel
	 * @author Joep Kemperman
	 */
	public void reset() {
		invalidate();
		removeAll();
		getGraphics().clearRect(0, 0, getWidth(), getHeight());
	}
	
	/**
	 * Draw the damn thing!
	 * @author Kay van Bree
	 * @param g 
	 */
	@Override
	protected void paintComponent(Graphics g){
		super.paintComponent(g);
		if(isGraph(info)){
			drawPie(g);
			drawLegend(g);
			Content.log.println("Drawing a pie chart...");
		}
	}
	
	/**
	 * Draw the Pie Chart and the slices
	 * @author Kay van Bree
	 * @param g 
	 */
	public void drawPie(Graphics g){		
		// Starting coördinates and dimensions of the pie chart
		int x = 82;
		int y = 48;
		int pWidth = 250;
		int pHeight = 250;
		
		// Graphics
		Graphics2D g2d = (Graphics2D) g;
		BufferedImage image = new BufferedImage(pWidth, pHeight, BufferedImage.TYPE_INT_ARGB);
		Graphics2D ig = image.createGraphics();
		
		ig.setColor(this.getBackground());
		ig.fillRect(0, 0, pWidth, pHeight);
		ig.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		
		double startAngle = 90;
		for(Slice slice: slices){
			Arc2D.Double arc = new Arc2D.Double(Arc2D.PIE);
			arc.setFrame(0, 0, pWidth, pHeight);
			arc.setAngleStart(startAngle);
			arc.setAngleExtent(-slice.getDegrees());
			ig.setColor(slice.getColor());
			ig.draw(arc);
			ig.fill(arc);
			startAngle -= slice.getDegrees();
		}
		
		g2d.drawImage(image, x, y, this);
		
		// Draw a circle around it
//		g.setColor(Color.BLACK);
//		g.drawOval(x, y, pWidth, pHeight);
	}
	
	/**
	 * Draw the legend next to the Pie chart
	 * @author Kay van Bree
	 * @param g 
	 */
	public void drawLegend(Graphics g){
		// The starting coördinates of this Legend
		int x = 370;
		int y = 48;
		int i = 0;
		
		// The row of the legend
		int r = 1;
		
		for(Slice slice: slices){
			if(i > 20){
				r++;
				if(r > 2){
					x -= 195*2;
					y = 308;
				} else {
					x += 195;
					y = 48;
				}
				i = 0;
			}
			// Draw square
			g.setColor(slice.getColor());
			g.fillRect(x, y, 15, 15);
			
			// Draw String
			g.setColor(Color.BLACK);
			g.drawString(slice.getName(), x+20, y+12);
			g.drawString(Integer.toString((int) slice.getValue()), x+165, y+12);
			y += 20;
			i++;
		}
	}
	
	/**
	 * Returns the sum of the provided information list.
	 * @author Kay van Bree
	 * @param info
	 * @return Sum of the provided information list.
	 */
	public int getSum(ArrayList<String[]> info){
		int sum = 0;
		for(String[] row: info){
			sum += Integer.valueOf(row[1]);
		}
		System.out.println("Sum: " + sum);
		return sum;
	}
			
	
	/**
	 * Removes all components and shows the user the current 
	 * management information is not suitable for a pie chart.
	 */
	public void setInformationNotSuitable() {
		invalidate();
		reset();
		add(new JLabel("This information is not suitable for Pie Chart view!"));
		validate();
		repaint();
	}
	
	/**
	 * Checks if the information is suitable for Bar Graph view
	 * @author Kay van Bree
	 * @param info
	 * @return True if info can be used for a bar graph
	 */
	public boolean isGraph(ArrayList<String[]> info) {
		if(info == null){
			return false;
		}
		if(info.size() > cap){
			return false;
		}
		String[] string = info.get(0);
		try{
			Integer.parseInt(string[1]);
		} catch(Exception e){
			return false;
		}
		return true;
	}

	/**
	 * This is what happens if the information has to many slices,
	 * We don't have that much colors, and we don't want to add more,
	 * because I'm kind of lazy, so you should do with 10 Color max
	 * @author Kay van Bree
	 */
	private void setOutOfBoundsException() {
		throw new UnsupportedOperationException("Not yet implemented");
	}
	
	/**
	 * This represents a slice in the Pie
	 * @author Kay van Bree
	 */
	private class Slice {
		private double degrees;
		private String name;
		private Color color;
		private double value;
		
		/**
		 * Slice has important things for drawing, like angle and color.
		 * @author Kay van Bree
		 * @param name
		 * @param value
		 * @param color 
		 */
		public Slice(String name, double value, Color color){
			this.name = name;
			this.degrees = calcDegrees(value);
			this.value = value;
			this.color = color;
		}
		
		/**
		* Calculates and returns the degrees of this Slice
		* @author Kay van Bree
		* @param value
		* @return 
		*/
		private double calcDegrees(double value){
			double dgr;
			dgr = (value * 360) / sum;		
			return dgr;
		}
		
		/**
		 * Returns the name
		 * @author Kay van Bree
		 * @return 
		 */
		public String getName(){
			return name;
		}
		
		/**
		 * Returns the degrees
		 * @author Kay van Bree
		 * @return 
		 */
		public double getDegrees(){
			return degrees;
		}
		
		/**
		 * Return value
		 * @author Kay van Bree
		 * @return 
		 */
		public double getValue(){
			return value;
		}
		
		/**
		 * Returns the color
		 * @author Kay van Bree
		 * @return 
		 */
		public Color getColor(){
			return color;
		}
		
		/**
		 * ToString dudes
		 * @author Kay van Bree
		 */
		@Override
		public String toString(){
			return "Name: " + name + "; Degrees: " + degrees + " Color: " + color + " Value: " + value;
		}
	}
}
